/**
 * Table of Pairs
 * Object created for Table from JPaveFraem.handleLoadQuery
 */
package jpave.query_interface;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;

import jpave.dataholders.MainData;
import jpave.dataholders.QueryData;
import jpave.manager.ManagerFrame;
import util.methods.UIHelpers;
import util.methods.StringHelpers;
import util.ui.CachedTable;
import util.ui.UserPrompt;

public class ContigPairListTab extends Tab
{	
	public ContigPairListTab ( 	JPaveFrame parentFrame, 
								FieldMapper inIndexer, 
								QueryData inQuery,				
								String inCacheFileName ) 
	throws Exception
	{
		super(parentFrame, null);
		super.setBackground(Color.WHITE);
		// Save references to inputs
		theQuery = inQuery;
		theFields = inIndexer;
		
		// Button panel	
		btnViewCluster = new JButton ("Align Selected Pair");
		btnViewCluster.setBackground(ManagerFrame.FUNCTIONCOLOR);
		btnViewCluster.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				addPairViewTab();
			}
		});
		btnViewCluster.setEnabled(false);
		
		JButton btnRefresh = new JButton ("Refresh Columns");
		btnRefresh.addActionListener(refreshListener);
		
		JButton btnCopy = new JButton ("Copy to Query");
		btnCopy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				QueryTab tab = (QueryTab)getParentFrame().getQueryTab();
				tab.setUIFromFilter(theQuery);
			}
		});
		
		JButton btnSave = new JButton("Export"); 
		btnSave.setBackground(ManagerFrame.PROMPTCOLOR);
		btnSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				final JFileChooser fc = new JFileChooser(getParentFrame().lastSaveFilePath);
				if (fc.showSaveDialog(ContigPairListTab.this) == JFileChooser.APPROVE_OPTION) {
					final File f = fc.getSelectedFile();
					int writeOption = JOptionPane.YES_OPTION;
					if (f.exists()) {
						writeOption = JOptionPane.showConfirmDialog(
								ContigPairListTab.this,
							    "The file already exists, overwrite it?",
							    "Save to File",
							    JOptionPane.YES_NO_OPTION);
					}
					if (writeOption == JOptionPane.YES_OPTION) {
						getParentFrame().lastSaveFilePath = f.getPath();
						Thread theThread = new Thread(new Runnable() {
							public void run() {
								//contigPairTable.saveToFile(f);
							}
						});
						theThread.start();
					}
				}
			}
		});	

		JButton btnHelp = new JButton("Help");
		btnHelp.setBackground(ManagerFrame.HELPCOLOR);
		btnHelp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				UserPrompt.displayHTMLResourceHelp(getParentFrame(), "Pairs Table", "html/viewSingleTCW/ContigPairListTab.html");
			}
		});

		// Top panel with buttons and drop-down
		JPanel topPanel = new JPanel ( );
		topPanel.setBackground(Color.WHITE);
		topPanel.add( Box.createHorizontalStrut(5) );
		topPanel.add( Box.createHorizontalStrut(5) );
		topPanel.add( btnViewCluster );
		topPanel.add( Box.createHorizontalGlue() );
		topPanel.add(btnRefresh);
		//topPanel.add(btnSave); CAS 12/16/14 doesn't work
		topPanel.add( Box.createHorizontalStrut(5) );
		topPanel.add(btnHelp);
		topPanel.add( Box.createHorizontalStrut(5) );
		topPanel.setMaximumSize( new Dimension ( Integer.MAX_VALUE, 
				(int)topPanel.getPreferredSize ().getHeight() ) );
	
		contigPairTable = new CachedTable ( 
			theFields, 
			inCacheFileName, 
			theFields.getVisibleFieldIDs(),
			refreshListener
		);
		contigPairTable.addSelectionChangeListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				if(contigPairTable.getSelectedRowCount() == 0) {
					if(btnViewCluster != null)
						btnViewCluster.setEnabled(false);
				}
				else {
					if(btnViewCluster != null)
						btnViewCluster.setEnabled(true);
				}
			}
		});
		contigPairTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
		contigPairTable.setOnlySingleRowSelection ( );
		contigPairTable.getTableHeader().setBackground(Color.WHITE);
		contigPairTable.addDoubleClickListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				addPairViewTab();
			}
		});
		
		// Scroll panel
		JScrollPane scroller = new JScrollPane ( contigPairTable );
		scroller.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
		scroller.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED );
		scroller.getViewport().setBackground(Color.WHITE);
		UIHelpers.setScrollIncrements( scroller );
		
		lblSummary = new JLabel ( "Displaying " + contigPairTable.getEntryCount() 
				+ " of " + contigPairTable.getEntryCount() + " contig pairs" );
		
		// Add to the called object's panel
		setLayout( new BoxLayout ( this, BoxLayout.Y_AXIS ) );
        add ( Box.createVerticalStrut(5) );
        add ( lblSummary );
        add ( Box.createVerticalStrut(5) );
        add ( topPanel );
		add ( Box.createVerticalStrut(5) );
		add ( scroller );
	}
	
	private ActionListener refreshListener = new ActionListener() {
		public void actionPerformed(ActionEvent event) {
			doRefreshColumns();
		}
	};
	
	public QueryData getQuery () { return theQuery; }
	
	private void doRefreshColumns() {
		getParentFrame().handleLoadQuery( ContigPairListTab.this, theQuery, null );
	}
	
	// a row in the Pairs table has been selected for viewing
	// add the tab on the left
	private void addPairViewTab ()
	{
		int nRow = contigPairTable.getSelectedRow();
		
		if ( nRow != -1 ) {
			// Open the cluster tab
			MainData theCluster = new MainData ();		
			String[] strContigIDs = getContigIDsAtRow( nRow );
			theCluster.addContigStub( strContigIDs[0] );
			if ( !StringHelpers.isEmpty(strContigIDs[1]) )
				theCluster.addContigStub( strContigIDs[1] );

			// in ClusterView, it also makes a tab title when replacing with Next/Prev
			String strTitle; 
			int pairNum = getPairNumAtRow( nRow );
			strTitle = "Pair #" + pairNum;

			// in JPaveFrame, which creates a ClusterView Object
			getParentFrame().addClusterPage(theCluster, strTitle, ContigPairListTab.this, nRow);
		}
	}

	public String[] getContigIDsAtRow( int nRow )
	{
		String[] contigIDs = new String[2];
		
		if ( nRow < 0 || nRow >= contigPairTable.getEntryCount() )
			return null;
		
		Object[] row = (Object[])contigPairTable.getRowAt(nRow);
		contigIDs[0] = (String)theFields.extractFieldByID( row, QueryData.FIELD_ID_CONTIG_1 );
		contigIDs[1] = (String)theFields.extractFieldByID( row, QueryData.FIELD_ID_CONTIG_2 );
		
		return contigIDs;
	}
	
	public int getPairNumAtRow( int nRow )
	{
		if ( nRow < 0 || nRow >= contigPairTable.getEntryCount() )
			return -1;
		
		int num = 0;
		Object[] row = (Object[])contigPairTable.getRowAt( nRow );
		try {
			num = Integer.valueOf( (String)theFields.extractFieldByID( row, QueryData.RECORD_NUM_FIELD ));
		}
		catch (NumberFormatException e) { 
			return -1; // if Pairs# columns not shown in table, get this error
		}
		return num;
	}
	
	public FieldMapper getFieldMapper()
	{
		return theFields;
	}
	
	public int getNextRowNum ( int nRow )
	{
		int nNextRow = nRow + 1;
		if (nNextRow >= contigPairTable.getVisibleRowCount()) 
			nNextRow = 0; // wrap-around
		return nNextRow;
	}
	
	public int getPrevRowNum ( int nRow )
	{
		int nPrevRow = nRow - 1;
		if (nPrevRow < 0)
			nPrevRow = contigPairTable.getVisibleRowCount() - 1; // get last row
		return nPrevRow;
	}

	/**
	 * Remove cache and free memory
	 */
	public void close() {
		contigPairTable.removeCache();
		if(theQuery != null) theQuery.clear();
		contigPairTable = null;
		theFields = null;
		lblSummary = null;
	}
	
	private QueryData theQuery = null;
	private CachedTable contigPairTable;
	private FieldMapper theFields;
	private JLabel lblSummary = null;
	private JButton btnViewCluster;
	
    private static final long serialVersionUID = 1;
}
